package heap

import (
	"fmt"
	"gvm/classfile"
)

// 为啥这里要用any类型???
type Constant interface{}

type ConstantPool struct {
	// 所属的class
	class *Klass
	// 常量池的常量
	constants []Constant
}

func NewConstantPool(class *Klass, cfCp classfile.ConstantPool) *ConstantPool {
	cpCount := len(cfCp)
	consts := make([]Constant, cpCount)
	rtCp := &ConstantPool{class: class, constants: consts}
	for i := 1; i < cpCount; i++ {
		cpInfo := cfCp[i]
		switch cp := cpInfo.(type) {
		case *classfile.Constant_Integer:
			consts[i] = cp.Value
			break
		case *classfile.Constant_Float:
			consts[i] = cp.Value
			break
		case *classfile.Constant_Long:
			consts[i] = cp.Value
			i++
			break
		case *classfile.Constant_Double:
			consts[i] = cp.Value
			i++
			break
		case *classfile.Constant_String:
			consts[i] = cp.StringValue()
			break
		case *classfile.Constant_Class:
			consts[i] = NewClassRef(rtCp, cp)
			break
		case *classfile.Constant_Field_Ref:
			consts[i] = NewFieldRef(rtCp, cp)
			break
		case *classfile.Constant_Method_Ref:
			consts[i] = NewMethodRef(rtCp, cp)
			break
		case *classfile.Constant_Interface_Method_Ref:
			//consts[i] = NewInterfaceMethodRef(rtCp, cp)
			break
		default:
			// todo
		}
	}

	return rtCp
}

func (cp *ConstantPool) GetConstant(index uint) Constant {
	if c := cp.constants[index]; c != nil {
		return c
	}
	panic(fmt.Sprintf("No constants at index %d", index))
}
